﻿using System.Globalization;
using GamFi.API.Application.Contracts.User.GetLeaderboard;
using GamFi.API.Application.Contracts.User.GetUser;
using GamFi.API.Application.Contracts.User.GetUserById;
using GamFi.API.Application.Contracts.User.PatchChangeCulture;
using GamFi.API.Application.Contracts.User.PatchUpdateUserInfo;
using GamFi.API.Application.Features.Queries.User.GetLeaderboard;
using GamFi.API.Application.Features.Queries.User.GetUser;
using GamFi.API.Application.Features.Queries.User.GetUserById;
using GamFi.API.Application.Features.Queries.User.PatchUpdateUserInfo;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;

namespace GamFi.API.WEB.Controllers;

/// <summary>
/// Контроллер отвечающий за действия с аккаунтом
/// </summary>
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
    private readonly IMediator _mediator;

    /// <summary>
    /// Конструктор
    /// </summary>
    /// <param name="mediator">Медиатор из библиотеки MediatR</param>
    public UserController(IMediator mediator) => _mediator = mediator;

    /// <summary>
    /// Запрос текущего пользователя
    /// </summary>
    /// <returns>GetUserResponse(Id, Email, UserName, Roles, UserPhotoId)</returns>
    [HttpGet("GetUser")]
    public async Task<GetUserResponse> GetUser(CancellationToken cancellationToken)
        => await _mediator.Send(new GetUserQuery(), cancellationToken);

    /// <summary>
    /// Запрос пользователя по ИД
    /// </summary>
    /// <returns>GetUserResponse(Id, UserName, FirstName, LastName, Patronymic, CountryId)</returns>
    [AllowAnonymous]
    [HttpGet("GetUserInfoById/{id:guid}")]
    public async Task<GetUserByIdResponse> GetUserInfoById(Guid id, CancellationToken cancellationToken)
        => await _mediator.Send(new GetUserByIdQuery(id), cancellationToken);

    /// <summary>
    /// Запрос пользователей с балансом + пагинация
    /// </summary>
    /// <param name="request"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpGet("GetLeaderboard")]
    public async Task<GetLeaderboardResponse> GetLeaderboard([FromQuery] GetLeaderboardRequest request,
        CancellationToken cancellationToken)
        => await _mediator.Send(new GetLeaderboardQuery(request), cancellationToken);

    /// <summary>
    /// Обновление данных пользователя
    /// </summary>
    /// <param name="request">PatchUpdateUserInfoRequest</param>
    /// <param name="cancellationToken">Токен отмены</param>
    [HttpPatch("UpdateUserInfo")]
    public async Task UpdateUserInfo([FromBody] PatchUpdateUserInfoRequest request,
        CancellationToken cancellationToken)
        => await _mediator.Send(new PatchUpdateUserInfoCommand(request), cancellationToken);

    /// <summary>
    /// Смена культуры
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpPatch("ChangeCulture")]
    public Task<IActionResult> ChangeCulture([FromBody] PatchChangeCultureRequest request, CancellationToken cancellationToken)
    {
        if (string.IsNullOrEmpty(request.Culture))
            return Task.FromResult<IActionResult>(BadRequest("Culture is required."));

        try
        {
            var newCulture = new CultureInfo(request.Culture);
            
            Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(newCulture.Name)),
                new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
            );

            return Task.FromResult<IActionResult>(Ok($"Language Changed Successfully - {newCulture.Name}"));
        }
        catch (CultureNotFoundException)
        {
            return Task.FromResult<IActionResult>(BadRequest($"Invalid culture: {request.Culture}"));
        }
    }
}